<template>
  <div class="content">
    <div class="header">
      <div>聊天室({{ state.count.all }})</div>
      <div class="online">当前在线人数：{{ state.count.online }}</div>
    </div>
    <div class="main">
      <div v-for="item in state.msgList" :key="item.id">
        <div class="item mymsg" v-if="item.userId === state.userInfo.id">
          <div>{{ item.userName }}</div>
          <div class="msg">{{ item.text }}</div>
        </div>
        <div class="item" v-else>
          <div>{{ item.userName }}</div>
          <div class="msg">{{ item.text }}</div>
        </div>
      </div>
    </div>
    <div class="footer">
      <input
        v-on:keyup.enter="sendMsg"
        type="text"
        placeholder="请输入内容"
        v-model="state.msg"
      />
      <button @click="sendMsg">发送</button>
    </div>

    <!-- 动画播放器 -->
    <div class="lottie-view" v-if="isPlaying">
      <div id="lottie"></div>
      <div>欢迎 {{ currJoinUser }} 加入群聊</div>
    </div>
  </div>
</template>

<script setup>
import lottie from "lottie-web";
import { nextTick, ref, onMounted, reactive, onUnmounted } from "vue";
import { useRoute } from "vue-router";
import io from "socket.io-client";
import http from "../../utils/http";
import vipJoin from "../assets/vipjoin.json";

// 动画逻辑
const animation = ref(null);
const isPlaying = ref(false);
const currJoinUser = ref(null);

const toggleAnimation = () => {
  if (isPlaying.value) return;
  isPlaying.value = true;
  nextTick(() => {
    animation.value = lottie.loadAnimation({
      container: document.getElementById("lottie"),
      renderer: "canvas",
      loop: false,
      autoplay: true,
      animationData: vipJoin,
    });
    animation.value.addEventListener("complete", () => {
      isPlaying.value = false;
    });
  });
};

// ------------------分隔符号-------------------//
// 连接到后端
const socket = io("ws://localhost:3001", {
  transports: ["websocket", "polling"],
  withCredentials: true,
});

const route = useRoute();
const state = reactive({
  msg: "",
  msgList: [],
  count: {
    all: 0,
    online: 0,
  },
  userInfo: {
    id: parseInt(route.query.id),
    userName: route.query.userName,
    roomId: 1, // 房间号暂时固定为1
  },
});

function sendMsg() {
  let sendData = {
    roomId: state.userInfo.roomId,
    userId: state.userInfo.id,
    userName: state.userInfo.userName,
    text: state.msg,
  };
  state.msg = "";
  // 发送消息
  socket.emit("send", sendData);
}

// 获取历史消息
async function getHistoryMsg() {
  const res = await http.get("/message/list");
  state.msgList = res.data;
}

onMounted(() => {
  socket.on("connect", async () => {
    // 获取历史消息
    await getHistoryMsg();
    // main 滑动到底部
    nextTick(() => {
      const main = document.querySelector(".main");
      main.scrollTop = main.scrollHeight;
    });
    // 连接到房间
    socket.emit("join", state.userInfo);
    // 更新数量
    socket.on("userCount", (data) => {
      state.count.all = data.all;
      state.count.online = data.online;
      currJoinUser.value = data.userName;
      // 判断用户名称是否包含vip
      if (data.userName && data.userName.startsWith("vip")) {
        toggleAnimation();
      }
    });
    // 监听消息
    socket.on("message", (data) => {
      // 将消息添加到列表
      state.msgList.push(data);
      // main 滑动到底部
      nextTick(() => {
        const main = document.querySelector(".main");
        main.scrollTop = main.scrollHeight;
      });
    });
  });
});

// 组件销毁时关闭连接
onUnmounted(() => {
  socket.close();
});
</script>

<style scoped lang="scss">
.content {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  height: 100%;
}
.header {
  height: 45px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  .online {
    font-size: 12px;
    color: #999;
    position: relative;
  }
  .online::before {
    content: "";
    position: absolute;
    width: 10px;
    height: 10px;
    background-color: #09d638;
    border-radius: 50%;
    left: -15px;
    top: 5px;
  }
}

.main {
  height: calc(100% - 95px);
  background-color: #f6f6f6;
  padding: 2%;
  overflow: auto;
  .item {
    margin-bottom: 10px;
    .msg {
      max-width: 80%;
      padding: 10px;
      border-radius: 5px;
      display: inline-block;
      text-align: left;
      margin-top: 2px;
      background-color: #ffffff;
    }
  }
  .mymsg {
    text-align: right;
    .msg {
      background-color: #e6e1f5;
    }
  }
}

.footer {
  height: 50px;
  background-color: #ffffff;
  padding: 5px;
  display: flex;
  box-sizing: border-box;
  align-items: center;

  input {
    flex: 1;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
  }
  button {
    width: 18%;
    padding: 10px;
    border: none;
    border-radius: 50px;
    background-image: linear-gradient(-90deg, #a18cd1 0%, #fbc2eb 100%);
    color: #ffffff;
    margin-left: 2%;
    height: 35px;
  }
}

.lottie-view {
  position: absolute;
  top: 10%;
  left: 0;
  text-align: center;
}
</style>
